# +----------------------------------------------------------------------
# | ChatWork
# +----------------------------------------------------------------------
# | 这不是一个自由软件,您只能在不用于商业目的的前提下对程序代码进行修改和使用。
# | 任何企业和个人不允许对程序代码以任何形式任何目的再发布,商业使用请获取授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from tortoise.queryset import Q
from hypertext import PagingResult
from exception import AppException
from common.utils.times import TimeUtil
from common.utils.tools import ToolsUtil
from common.enums.agent import AgentEnum
from common.models.agents import AgentRobotModel
from common.models.agents import AgentRobotPublishModel
from apps.api.schemas.agent.robot import publish_schema as schema
from apps.api.service.agent.robot.teamed_service import RobotTeamedService


class RobotPublishService:
    """ 智能体发布服务类 """

    @classmethod
    async def lists(cls, params: schema.RobotPublishSearchIn, user_id: int) -> PagingResult[schema.RobotPublishListVo]:
        """
        发布列表。

        Args:
            params (schema.RobotPublishSearchIn): 发布查询参数。
            user_id (int): 用户ID。

        Returns:
            PagingResult[schema.RobotSmarterListVo]: 智能体分页列表Vo。

        Author:
            zero
        """
        # 验证智能体
        robot = await AgentRobotModel.filter(code=params.bot, is_delete=0).first()
        if robot is None:
            raise AppException("智能体不存在!")
        if robot.is_disable:
            raise AppException("智能体被禁用!")

        # 验证权限
        await RobotTeamedService.has_permission(robot.code, user_id, AgentEnum.POWER_VIEW)

        # 查询列表
        _where = [Q(scene=params.scene), Q(robot_id=robot.id), Q(is_delete=0)]
        _model = AgentRobotPublishModel.filter(*_where).order_by("-id")
        _pager = await AgentRobotPublishModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size,
            fields=AgentRobotPublishModel.without_field("is_delete,delete_time")
        )

        # 处理数据
        _lists = []
        for item in _pager.lists:
            is_expire = False
            if item["expire_time"] and item["expire_time"] - int(time.time()) <= 0:
                is_expire = True

            _lists.append(schema.RobotPublishListVo(
                id=item["id"],
                scene=item["scene"],
                name=item["name"],
                api_key=item["api_key"],
                api_secret=item["api_secret"],
                max_points=item["max_points"],
                use_points=item["use_points"],
                call_count=item["call_count"],
                rpm_limit=item["rpm_limit"],
                is_expire=is_expire,
                create_time=item["create_time"],
                update_time=item["update_time"],
                expire_time=TimeUtil.timestamp_to_date(item["expire_time"]) if item["expire_time"] else "-",
                last_time=TimeUtil.timestamp_to_date(item["last_time"]) if item["last_time"] else "-",
            ))

        _pager.lists = _lists
        return _pager

    @classmethod
    async def add(cls, post: schema.RobotPublishAddIn, user_id: int):
        """
        发布创建。

        Args:
            post (schema.RobotPublishAddIn): 发布创建参数。
            user_id (int): 用户ID。

        Author:
            zero
        """
        # 验证智能体
        robot = await AgentRobotModel.filter(code=post.bot, is_delete=0).first()
        if robot is None:
            raise AppException("智能体不存在!")
        if robot.is_disable:
            raise AppException("智能体被禁用!")

        # 验证权限
        await RobotTeamedService.has_permission(robot.code, user_id, AgentEnum.POWER_ADMIN)

        # 生成密钥
        rand = ToolsUtil.make_rand_char(20) + robot.code
        keys = ToolsUtil.make_md5_str(str(time.time()), rand)

        # 创建发布
        await AgentRobotPublishModel.create(
            scene=post.scene,
            name=post.name,
            robot_id=robot.id,
            api_key="sk-" + keys,
            api_secret=post.api_secret,
            max_points=post.max_points,
            rpm_limit=post.rpm_limit,
            expire_time=post.expire_time,
            create_time=int(time.time()),
            update_time=int(time.time())
        )

    @classmethod
    async def edit(cls, post: schema.RobotPublishEditIn, user_id: int):
        """
        发布创建。

        Args:
            post (schema.RobotPublishEditIn): 发布编辑参数。
            user_id (int): 用户ID。

        Author:
            zero
        """
        # 验证数据
        publish = await AgentRobotPublishModel.filter(id=post.id, is_delete=0).get()

        # 验证智能体
        robot = await AgentRobotModel.filter(id=publish.robot_id, is_delete=0).first()
        if robot is None:
            raise AppException("智能体不存在!")
        if robot.is_disable:
            raise AppException("智能体被禁用!")

        # 验证权限
        await RobotTeamedService.has_permission(robot.code, user_id, AgentEnum.POWER_ADMIN)

        # 更新发布
        await AgentRobotPublishModel.filter(id=post.id).update(
            name=post.name,
            api_secret=post.api_secret,
            max_points=post.max_points,
            rpm_limit=post.rpm_limit,
            expire_time=post.expire_time,
            update_time=int(time.time())
        )

    @classmethod
    async def delete(cls, id_: int, user_id: int):
        """
        发布删除。

        Args:
            id_ (int): 发布ID。
            user_id (int): 用户ID。

        Author:
            zero
        """
        # 验证数据
        publish = await AgentRobotPublishModel.filter(id=id_, is_delete=0).get()

        # 验证智能体
        robot = await AgentRobotModel.filter(id=publish.robot_id, is_delete=0).first()
        if robot is None:
            raise AppException("智能体不存在!")
        if robot.is_disable:
            raise AppException("智能体被禁用!")

        # 验证权限
        await RobotTeamedService.has_permission(robot.code, user_id, AgentEnum.POWER_ADMIN)

        # 删除发布
        await AgentRobotPublishModel.filter(id=id_).update(
            is_delete=1,
            delete_time=int(time.time())
        )
